package com.mall.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.mall.api.dto.OrderDetailDTO;
import com.mall.common.exception.GlobalException;
import com.mall.product.entity.dto.ProductQueryDTO;
import com.mall.product.entity.po.Product;
import com.mall.product.entity.po.ProductCategory;
import com.mall.product.entity.po.ProductImage;
import com.mall.product.entity.vo.ProductDetailVO;
import com.mall.product.mapper.ProductMapper;
import com.mall.product.service.ProductCategoryService;
import com.mall.product.service.ProductImageService;
import com.mall.product.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    private final ProductCategoryService productCategoryService;

    private final ProductImageService productImageService;
    /**
     * 分页查询商品列表
     */
    @Override
    public IPage<Product> getProductPage(ProductQueryDTO queryDTO) {
        Page<Product> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        BigDecimal minPrice = queryDTO.getMinPrice() != null ? BigDecimal.valueOf(queryDTO.getMinPrice()) : null;
        BigDecimal maxPrice = queryDTO.getMaxPrice() != null ? BigDecimal.valueOf(queryDTO.getMaxPrice()) : null;

        // 构建查询条件
        return lambdaQuery()
                .eq(queryDTO.getCategoryId() != null, Product::getCategoryId, queryDTO.getCategoryId())
                .like(queryDTO.getKeyword() != null && !queryDTO.getKeyword().trim().isEmpty(), Product::getTitle, queryDTO.getKeyword())
                .ge(minPrice != null, Product::getPrice, minPrice)
                .le(maxPrice != null, Product::getPrice, maxPrice)
                .eq(queryDTO.getStatus() != null, Product::getStatus, queryDTO.getStatus())
                .orderByDesc(Product::getSellCount)
                .orderByDesc(Product::getCreateTime)
                .page(page);
    }
    /**
     * 获取商品详情
     */
    @Override
    public ProductDetailVO getProductDetail(Long productId) {
        // 1. 查询商品基本信息
        Product product = getById(productId);
        if (product == null || product.getStatus() == 0) {
            throw new GlobalException("商品不存在或已下架");
        }

        ProductDetailVO vo = new ProductDetailVO();
        BeanUtils.copyProperties(product, vo);

        // 2. 查询分类名称
//        ProductCategory category = Db.getById(product.getCategoryId(),ProductCategory.class);
        ProductCategory category = productCategoryService.getById(product.getCategoryId());
        if (category != null) {
            vo.setCategoryName(category.getName());
        }

        // 3. 查询商品图片
        List<ProductImage> images = productImageService.list(
                new LambdaQueryWrapper<ProductImage>()
                        .eq(ProductImage::getProductId, productId)
                        .orderByAsc(ProductImage::getSort)
        );

        if (CollUtil.isNotEmpty(images)) {
            List<String> mainImages = images.stream()
                    .filter(img -> Objects.equals(img.getImgType(), 1)) // 主图
                    .map(ProductImage::getImgUrl)
                    .collect(Collectors.toList());
            vo.setMainImages(mainImages);

            List<String> detailImages = images.stream()
                    .filter(img -> Objects.equals(img.getImgType(), 2)) // 详情图
                    .map(ProductImage::getImgUrl)
                    .collect(Collectors.toList());
            vo.setDetailImages(detailImages);
        }

        // 4. 格式化时间
        vo.setCreateTime(product.getCreateTime().toString());

        return vo;
    }
    /**
     * 上下架商品
     */
    @Override
    @Transactional
    public boolean changeProductStatus(Long productId, Integer status) {
        if (status != 0 && status != 1) {
            throw new GlobalException("商品状态参数不合法");
        }

        Product product = getById(productId);
        if (product == null) {
            throw new GlobalException("商品不存在");
        }

        // 更新状态
        product.setStatus(status);
        return updateById(product);
    }


    /**
     * 批量扣减库存
     */
    @Transactional(rollbackFor = Exception.class)
    public void deductStock(List<OrderDetailDTO> items) {
    String UPDATE_STOCK_SQL = "com.hmall.product.mapper.ProductMapper.deductStock";

        if (items == null || items.isEmpty()) {
            throw new GlobalException("订单详情不能为空");
        }

        // 使用 MP 内置的 executeBatch 批量操作
        boolean success = executeBatch(items, 100, (sqlSession, item) -> {
            int updatedRows = sqlSession.update(UPDATE_STOCK_SQL, item);
            if (updatedRows == 0) {
                throw new GlobalException("商品ID=" + item.getItemId() + " 库存不足，无法扣减！");
            }
        });

        if (!success) {
            throw new GlobalException("批量扣减库存失败，可能是部分商品库存不足或数据库异常");
        }
    }

    @Override
    public List<ProductDetailVO> getProductDetailBatch(List<Long> ids) {
        // 1. 查询所有有效的商品（只查上架的）
        List<Product> products = list(new LambdaQueryWrapper<Product>()
                .in(Product::getId, ids)
                .eq(Product::getStatus, 1) // 只查上架商品
        );

        if (products.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 转换为 VO
        List<ProductDetailVO> vos = products.stream()
                .map(product -> {
                    ProductDetailVO vo = new ProductDetailVO();
                    BeanUtils.copyProperties(product, vo);

                    // 设置 createTime 格式化
                    if (product.getCreateTime() != null) {
                        vo.setCreateTime(product.getCreateTime().toString());
                    }

                    return vo;
                })
                .toList();

        // 3. 按原始 ids 的顺序排序（重要！）
        Map<Long, ProductDetailVO> map = vos.stream()
                .collect(Collectors.toMap(ProductDetailVO::getId, vo -> vo));

        // 按传入的 ids 顺序返回
        return ids.stream()
                .map(map::get)
                .filter(Objects::nonNull) // 过滤掉查不到的商品
                .collect(Collectors.toList());
    }
}